package com.fessc.develop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fessc.develop.entity.comvo.SettlePurchaseOrderVo;
import com.fessc.develop.entity.dbvo.Enclosure;
import com.fessc.develop.entity.dbvo.SettleTrade;
import com.fessc.develop.entity.dbvo.TPayment;
import com.fessc.develop.entity.ccbvo.CCBSettleTradeSendBodyVo;
import com.fessc.develop.entity.ccbvo.CCBSubOrderBodyVo;
import com.fessc.develop.entity.comvo.SettleTradeSendBodyVo;
import com.fessc.develop.entity.comvo.SettleSaleOrderVo;
import com.fessc.develop.mapper.SettleTradeMapper;
import com.fessc.develop.model.enums.EnumPaymentStatus;
import com.fessc.develop.service.interfaces.IEnclosureService;
import com.fessc.develop.service.interfaces.ISettleTradeListService;
import com.fessc.develop.service.interfaces.ISettleTradeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fessc.develop.service.interfaces.ITPaymentService;
import com.fessc.develop.utils.BusiUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author y
 * @since 2024-06-27
 */
@Service
public class SettleTradeServiceImpl extends ServiceImpl<SettleTradeMapper, SettleTrade> implements ISettleTradeService {

    @Resource
    private ISettleTradeListService settleTradeListService;

    @Resource
    private ITPaymentService paymentService;

    @Resource
    private SettleTradeMapper settleTradeMapper;

    @Resource
    private IEnclosureService enclosureService;

    /**
     * 根据跨境付汇记录集，生成发送报报文体
     *
     * @param settleTrade 跨境付汇记录
     * @return 跨境付汇报文体
     */
    @Override
    public SettleTradeSendBodyVo fakeSettleTradeSendBody(SettleTrade settleTrade) {
        SettleTradeSendBodyVo crossBorderPaymentSendBody = new SettleTradeSendBodyVo();
        BeanUtils.copyProperties(settleTrade, crossBorderPaymentSendBody);
        List<Enclosure> enclosureList = enclosureService.getEnclosureListBySettleId(settleTrade.getSettleId());

        String fileIds = enclosureList.stream().map(Enclosure::getFileId).collect(Collectors.joining("|"));
        crossBorderPaymentSendBody.setFileId(BusiUtil.isNull(fileIds) ? "" : fileIds);

        //查询采购订单
        List<SettlePurchaseOrderVo> settlePurchaseOrderList = getSettleTradePurchaseOrderList(settleTrade.getOrderno());
        crossBorderPaymentSendBody.setPurchaseOrderList(settlePurchaseOrderList);

        // 按商品编码分组并统计
        Map<String, Long> settleCounts = settlePurchaseOrderList.stream()
                .collect(Collectors.groupingBy(vo -> vo.getGoodscode() + "@#%" + vo.getGoodsname(), Collectors.counting()));
        // 找出最大数量商品编码
        String goodsCode = settleCounts.entrySet().stream()
                .max(Map.Entry.comparingByValue()) // 按值（计数）比较找到最大值
                .map(Map.Entry::getKey) // 获取键（商品编码）
                .orElse(""); // 如果没有找到则返回空

        //查询销售订单
        List<SettleSaleOrderVo> settleSaleOrderList = getSettleTradeSaleOrderList(settleTrade.getOrderno());
        for (SettleSaleOrderVo settleSaleOrderVo : settleSaleOrderList) {
            settleSaleOrderVo.setGoodscode(BusiUtil.isNotNull(goodsCode) ? goodsCode.split("@#%")[0] : "");
            settleSaleOrderVo.setGoodsName(BusiUtil.isNotNull(goodsCode) ? goodsCode.split("@#%")[1] : "");
        }
        crossBorderPaymentSendBody.setSaleOrderList(settleSaleOrderList);
        return crossBorderPaymentSendBody;
    }

    /**
     * 根据跨境付汇记录集，生成发送报报文体
     *
     * @param settleTrade 跨境付汇记录
     * @return 跨境付汇报文体
     */
    @Override
    public CCBSettleTradeSendBodyVo fakeCCBSettleTradeSendBody(SettleTrade settleTrade) {
        CCBSettleTradeSendBodyVo ccbSettleTradeSendBodyVo = new CCBSettleTradeSendBodyVo();
        BeanUtils.copyProperties(settleTrade, ccbSettleTradeSendBodyVo);
        //组装子订单数组
        List<TPayment> tPaymentLists = paymentService.getSettleTradePaymentList(settleTrade.getOrderno());
        List<CCBSubOrderBodyVo> subOrderBodyVoList = new ArrayList<>();
        tPaymentLists.forEach(tPayment -> {
            CCBSubOrderBodyVo ccbSubOrderBodyVo = new CCBSubOrderBodyVo();
            ccbSubOrderBodyVo.setSubOrderNo(tPayment.getSuborderno());
            subOrderBodyVoList.add(ccbSubOrderBodyVo);
        });
        ccbSettleTradeSendBodyVo.setSubOrderList(subOrderBodyVoList);
        ccbSettleTradeSendBodyVo.setTotalCount(String.valueOf(tPaymentLists.size()));
        return ccbSettleTradeSendBodyVo;
    }

    /**
     * 根据订单编号和银行编号，查询跨境付汇记录集
     *
     * @param bankId      银行编号
     * @param termDate    查询时间
     * @param containType 包含条件
     * @return 跨境付汇集合
     */
    @Override
    public List<SettleTrade> getCCBSettleTradeByBankIdToPush(String bankId, String termDate, String containType) {
        QueryWrapper<SettleTrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("review_status", "0")
                .eq("order_status", "Y")
                .eq("payment_type", "B")
                .eq("payment_type_send", "N");
        if (BusiUtil.isNotNull(bankId) && BusiUtil.isEquals(containType, "Y")) {
            queryWrapper.eq("bankid", bankId);
        } else if (BusiUtil.isNotNull(bankId) && BusiUtil.isEquals(containType, "N")) {
            queryWrapper.ne("bankid", bankId);
        }
        if (BusiUtil.isNotNull(termDate)) {
            queryWrapper.ge("insert_date", termDate);
        }
        return this.list(queryWrapper);
    }

    /**
     * @param bankId      银行编号
     * @param termDate    查询时间
     * @param containType 包含条件
     * @return
     */
    @Override
    public List<SettleTrade> getSettleTradeByBankIdToPush(String bankId, String termDate, String containType) {
        return settleTradeMapper.getSettleTradeByBankIdToPush(bankId, termDate);
    }

    /**
     * 根据银行编号，查询跨境付汇待更新状态记录集
     *
     * @param bankId 银行编号
     * @return 跨境付汇集合
     */
    @Override
    public List<SettleTrade> getSettleTradeToUpdateStatusByBankId(String bankId, String termDate, String containType) {
        QueryWrapper<SettleTrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("review_status", "0");
        queryWrapper.eq("order_status", "Y");
        queryWrapper.eq("payment_type", "B");
        queryWrapper.eq("payment_type_send", "Y");
        if (BusiUtil.isNotNull(bankId) && BusiUtil.isEquals(containType, "Y")) {
            queryWrapper.eq("bankid", bankId);
        } else if (BusiUtil.isNotNull(bankId) && BusiUtil.isEquals(containType, "N")) {
            queryWrapper.ne("bankid", bankId);
        }
        queryWrapper.notIn("review_status", "2", "3");
        if (BusiUtil.isNotNull(termDate)) {
            queryWrapper.ge("insert_date", termDate);
        }
        return this.list(queryWrapper);
    }

    /**
     * 查询跨境付汇销售订单明细
     *
     * @param orderno 订单编号
     * @return 跨境付汇销售订单集合
     */
    @Override
    public List<SettleSaleOrderVo> getSettleTradeSaleOrderList(String orderno) {
        return settleTradeMapper.getSettleTradeSaleOrderList(orderno);
    }

    /**
     * 查询跨境付汇采购订单明细
     *
     * @param orderno 订单编号
     * @return 跨境付汇采购订单集合
     */
    @Override
    public List<SettlePurchaseOrderVo> getSettleTradePurchaseOrderList(String orderno) {
        return settleTradeMapper.getSettleTradePurchaseOrderList(orderno);
    }

    /**
     * 更新跨境付汇交易状态
     *
     * @param settleTrade 跨境付汇
     * @param tranType    也业务类型
     * @return 更新成功失败标志
     */
    @Override
    public Boolean updateSettleTradeStatusRefidsLog(SettleTrade settleTrade, String tranType) {
        UpdateWrapper<SettleTrade> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", settleTrade.getId());
        if (BusiUtil.isNotNull(settleTrade.getSettleId())) {
            updateWrapper.eq("settle_id", settleTrade.getSettleId());
        }
        if (BusiUtil.isNotNull(settleTrade.getOrderno())) {
            updateWrapper.eq("orderno", settleTrade.getOrderno());
        }
        if (BusiUtil.isEquals(EnumPaymentStatus.SEND.toString(), tranType)) {  //已发送银行
            // 更新跨境付汇发送银行状态
            updateWrapper.set("payment_type_send", settleTrade.getPaymentTypeSend());
        } else if (BusiUtil.isEquals(EnumPaymentStatus.PAYMENT_FAIL.toString(), tranType)) {  //交易失败
            // 更新跨境付汇发送银行状态
            updateWrapper.set("review_status", settleTrade.getReviewStatus());
            updateWrapper.set("reject_date", settleTrade.getRejectDate());
            updateWrapper.set("reject_performer", settleTrade.getRejectPerformer());
            updateWrapper.set("remark", settleTrade.getRemark());
            updateWrapper.set("cancel_send", settleTrade.getCancelSend());
        } else if (BusiUtil.isEquals(EnumPaymentStatus.PAYMENT_SUCCESS.toString(), tranType)) {  //交易成功
            // 将 review_status 更改为 2  ，deal_date 为当前时间，deal_performer 为银行直连机构号， review_date 为当前时间
            // 将 review_performer 为银行直连机构号，send2 更改为 N， serialnumber 更改 实际的跨境付款流水号
            // 更新跨境付汇交易成功状态
            updateWrapper.set("review_status", settleTrade.getReviewStatus());
            updateWrapper.set("deal_date", settleTrade.getDealDate());
            updateWrapper.set("deal_performer", settleTrade.getDealPerformer());
            updateWrapper.set("review_date", settleTrade.getReviewDate());
            updateWrapper.set("review_performer", settleTrade.getReviewPerformer());
            updateWrapper.set("send2", settleTrade.getSend2());
            updateWrapper.set("serialnumber", settleTrade.getSerialnumber());
        }
        return this.update(updateWrapper);
    }

    /**
     * 根据订单日期和银行编号，查询跨境付汇记录集
     *
     * @param settleDate 订单日期
     * @param bankId     银行编号
     * @return 跨境付汇集合
     */
    @Override
    public List<SettleTrade> getSettleTradeCheckingList(String settleDate, String bankId) {
        QueryWrapper<SettleTrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("DATE(insert_date)", settleDate)
                .eq("payment_type", "B")
                .ne("payment_type_send", "N");  //不为N代表已推送给银行

        if (BusiUtil.isNotNull(bankId)) {
            queryWrapper.eq("bankid", bankId);
        }
        return this.list(queryWrapper);
    }

    /**
     * 根据订单编号，查询跨境付汇记录
     *
     * @param orderNo 订单编号
     * @return 跨境付汇记录
     */
    @Override
    public SettleTrade getSettleTradeByOrderNos(String orderNo) {
        QueryWrapper<SettleTrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("orderno", orderNo);
        return this.getOne(queryWrapper);
    }

    /**
     * 根据业务核对编码，查询跨境付汇记录
     *
     * @param settleId 业务核对编码
     * @return 跨境付汇记录
     */
    @Override
    public SettleTrade getSettleTradeBySettleId(String settleId) {
        QueryWrapper<SettleTrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("settle_id", settleId);
        return this.getOne(queryWrapper);
    }


}
